home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’97 / MacMolecule2 a la Breakout / MacHack.c / Jetsons.c next >
Encoding:
C/C++ Source or Header  |  1997-06-28  |  11.2 KB  |  558 lines  |  [TEXT/CWIE]

  1. #include "osMacIncludes.h"
  2. #include "Jetsons.h"
  3. #include "Molecule.h"
  4. #include "osGraphics.h"
  5. #include "osMain.h"
  6. #include "osWindows.h"
  7. #include "Rotation.h"
  8. #include "User.h"
  9. #include "Windows.h"
  10. #include "Dispatch.h"
  11.  
  12. extern PrefsT gPrefs;
  13.  
  14. /* Start fun stuff */
  15.  
  16. /* Called from AutoRotate, but with Option-Key held down.
  17.    These functions are called _after_ render, but before the screen blit.
  18. */
  19.  
  20. void GameInit(GameState *game)
  21. {
  22.     game->state = STARTUP;
  23. }
  24.  
  25. void GetGameRect(WindowPtr theWindow, Rect *gameRect)
  26. {
  27.     GetMoleculeRect(theWindow, gameRect, TRUE);
  28.     ZeroRect(gameRect);
  29. }
  30.  
  31. void GameStartup(GameState *game, Rect *gameRect, WindowPtr theWindow)
  32. {    
  33.     DocInfoHand infoHand;
  34.     int i,sum;
  35.     unsigned char lightest,darkest; /* pix value */
  36.     int max = -INT_MAX;
  37.     int min = INT_MAX;
  38.     unsigned char *rmap,*gmap,*bmap;
  39.     
  40.     infoHand = (DocInfoHand) osGetWRefCon(theWindow);
  41.     
  42.     game->theWindow = theWindow;
  43.  
  44.   game->paddx = gameRect->right / 2;
  45.   game->paddy = gameRect->bottom;
  46.   
  47.   game->ballx = game->paddx;
  48.   game->bally = (game->paddy - (PADDSIZE/2)) - (BALLSIZE/2);
  49.     game->balldx = 0;
  50.     game->balldy = -3;
  51.     
  52.     game->score = 0;
  53.     
  54.   game->state = PLAYING;
  55.  
  56.   /* Get Colors */
  57.     rmap = (**infoHand).canvas.rmap;
  58.     gmap = (**infoHand).canvas.gmap;
  59.     bmap = (**infoHand).canvas.bmap;
  60.     
  61.     for (i = CTABLEFIRST; i <= CTABLELAST; i++) {
  62.         sum = rmap[i] + gmap[i] + bmap[i];
  63.         if (sum > max) {
  64.             max = sum;
  65.             lightest = i;
  66.         }
  67.         else if (sum < min) {
  68.             min = sum;
  69.             darkest = i;
  70.         }
  71.     }
  72.     
  73.     game->color = lightest;
  74.  
  75. }
  76.  
  77. void DrawGame(GameState *game, Rect *gameRect)
  78. {
  79.   DocInfoHand infoHand;
  80.   int rowbytes;
  81.   unsigned char *pix, *start, *ball;
  82.   int r,c;
  83.   Rect paddRect;
  84. #define dWIDTH  7
  85. #define dHEIGHT 7
  86.     unsigned char ds[dWIDTH * dHEIGHT] = { /* auto check size */
  87.         0xFF,0xFF,0x01,0x01,0x01,0xFF,0xFF,
  88.         0xFF,0x01,0x01,0x01,0x01,0x01,0xFF,
  89.         0x01,0x01,0x01,0x01,0x01,0x01,0x01,
  90.         0x01,0x01,0x01,0x01,0x01,0x01,0x01,
  91.         0x01,0x01,0x01,0x01,0x01,0x01,0x01,
  92.         0xFF,0x01,0x01,0x01,0x01,0x01,0xFF,
  93.         0xFF,0xFF,0x01,0x01,0x01,0xFF,0xFF
  94.     };
  95.   
  96.   infoHand = (DocInfoHand) osGetWRefCon(game -> theWindow);
  97.     rowbytes = (**infoHand).canvas.srow;
  98.     pix = (unsigned char *) (**infoHand).pixels;
  99.     
  100.     /* Draw paddle row 1 */
  101.     
  102.     paddRect.left = game->paddx - PADDSIZEHALF;
  103.     paddRect.right = game->paddx + PADDSIZEHALF;
  104.      paddRect.top = game->paddy - PADDSIZEHALF;
  105.     paddRect.bottom = game->paddy + PADDSIZEHALF;
  106.   SectRect(&paddRect, gameRect, &paddRect);
  107.         
  108.     start = pix + (rowbytes * paddRect.top);
  109.     for (r = paddRect.top; r < paddRect.bottom; r++) {
  110.         for (c = paddRect.left; c < paddRect.right; c++) {
  111.             *(start + c) = game->color;
  112.         }
  113.         start += rowbytes;
  114.     }
  115.     
  116.     /* Draw ball */
  117.     ball = ds;
  118.     start = pix + (rowbytes * (game->bally - BALLSIZEHALF));
  119.     for (r = 0; r < BALLSIZE; r++) {
  120.         for (c = game->ballx - BALLSIZEHALF; c <= game->ballx + BALLSIZEHALF; c++) {
  121.             if (*ball == 0x01) {
  122.                 *(start + c) = game->color;
  123.             }
  124.             ball += 1;
  125.         }
  126.         start += rowbytes;
  127.     }
  128.     
  129. }
  130.  
  131. void MovePaddleClockwise(GameState *game, Rect * gameRect)
  132. {
  133.     if (game->paddx == gameRect->left) {
  134.       if (game->paddy == gameRect->top) {
  135.         game->paddx += DISTANCE;
  136.       }
  137.       else {
  138.         game->paddy -= DISTANCE;
  139.       }
  140.     }
  141.     else if (game->paddy == gameRect->top) {
  142.       if (game->paddx == gameRect->right) {
  143.         game->paddy += DISTANCE;
  144.       }
  145.       else {
  146.         game->paddx += DISTANCE;
  147.       }
  148.     }
  149.     else if (game->paddx == gameRect->right) {
  150.       if (game->paddy == gameRect->bottom) {
  151.         game->paddx -= DISTANCE;
  152.       }
  153.       else {
  154.         game->paddy += DISTANCE;
  155.       }
  156.     }
  157.     else if (game->paddy == gameRect->bottom) {
  158.       if (game->paddx == gameRect->left) {
  159.         game->paddy -= DISTANCE;
  160.       }
  161.       else {
  162.         game->paddx -= DISTANCE;
  163.       }
  164.     }
  165.   
  166. }
  167.  
  168. void MovePaddleCounterClockwise(GameState *game, Rect * gameRect)
  169. {
  170.     if (game->paddx == gameRect->left) {
  171.       if (game->paddy == gameRect->bottom) {
  172.         game->paddx += DISTANCE;
  173.       }
  174.       else {
  175.         game->paddy += DISTANCE;
  176.       }
  177.     }
  178.     else if (game->paddy == gameRect->top) {
  179.       if (game->paddx == gameRect->left) {
  180.         game->paddy += DISTANCE;
  181.       }
  182.       else {
  183.         game->paddx -= DISTANCE;
  184.       }
  185.     }
  186.     else if (game->paddx == gameRect->right) {
  187.       if (game->paddy == gameRect->top) {
  188.         game->paddx -= DISTANCE;
  189.       }
  190.       else {
  191.         game->paddy -= DISTANCE;
  192.       }
  193.     }
  194.     else if (game->paddy == gameRect->bottom) {
  195.       if (game->paddx == gameRect->right) {
  196.         game->paddy -= DISTANCE;
  197.       }
  198.       else {
  199.         game->paddx += DISTANCE;
  200.       }
  201.     }
  202.   
  203. }
  204.  
  205. /*
  206. void DetermineKey(void);
  207. void DetermineKey(void)
  208. {
  209.   long option,i;
  210.     unsigned char km[16];
  211.  
  212.     Delay(120,&option);
  213.  
  214.     GetKeys((UInt32 *) km);
  215.     
  216.     for (i = 0; i < 128; i++) {
  217.       option  = ( ( km[i>>3] >> (i & 7) ) & 1);
  218.       if (option) {
  219.         Str255 s;
  220.         NumToString(option,s);
  221.       }
  222.     }
  223.     
  224. }
  225. */
  226.  
  227.  
  228.  
  229. long KeyIsDown(int KeyNum)
  230. {
  231.   long down;
  232.     unsigned char km[16];
  233.  
  234.     GetKeys((UInt32 *) km);
  235.  
  236.     down  = ( ( km[KeyNum>>3] >> (KeyNum & 7) ) & 1);
  237.     
  238.     return down;
  239. }
  240.  
  241. /*
  242.   if (CLOCKWISE != direction) {
  243.       speed = 1;
  244.       direction = CLOCKWISE;
  245.   }
  246.   else {
  247.   }
  248. */
  249. static int speed = 1;
  250. static int direction = 0;
  251. static int slowdown = 1;
  252.  
  253.  
  254. void GamePlaying(GameState *game, Rect *gameRect)
  255. {
  256.   int i;
  257.   DocInfoHand infoHand;
  258.   infoHand = (DocInfoHand) osGetWRefCon(game -> theWindow);
  259.  
  260.     /* DIRECTION */
  261.     
  262.   switch (direction) {
  263.     case COUNTERCLOCKWISE:
  264.      
  265.       if (KeyIsDown(RIGHT_ARROW)) {
  266.         if (KeyIsDown(LEFT_ARROW)) {
  267.           speed -= slowdown;
  268.           slowdown++;
  269.           if (speed <= 0) {
  270.                speed = 1;
  271.                slowdown = 1;
  272.           }
  273.         }
  274.         else {
  275.           speed += 1;
  276.           slowdown = 1;
  277.         }
  278.       }
  279.       else if (KeyIsDown(LEFT_ARROW)) {
  280.         direction = CLOCKWISE;
  281.         speed = 1;
  282.         slowdown = 1;
  283.       }
  284.       else {
  285.         speed = 0;
  286.         slowdown = 1;
  287.         direction = STATIONARY;
  288.       }
  289.       break;
  290.     
  291.     case CLOCKWISE:
  292.        if (KeyIsDown(LEFT_ARROW)) {
  293.         if (KeyIsDown(RIGHT_ARROW)) {
  294.           speed -= slowdown;
  295.           slowdown++;
  296.           if (speed <= 0) {
  297.               speed = 1;
  298.               slowdown = 1;
  299.           }
  300.         }
  301.         else {
  302.           speed += 1;
  303.           slowdown = 1;
  304.         }
  305.       }
  306.       else if (KeyIsDown(RIGHT_ARROW)) {
  307.         direction = COUNTERCLOCKWISE;
  308.         speed = 1;
  309.         slowdown = 1;
  310.       }
  311.       else {
  312.         speed = 0;
  313.         slowdown = 1;
  314.         direction = STATIONARY;
  315.       }
  316.       break;
  317.       
  318.     case STATIONARY:
  319.             if (KeyIsDown(LEFT_ARROW)) {
  320.               direction = CLOCKWISE;
  321.               speed = 1;
  322.               slowdown = 1;
  323.             }
  324.             else if (KeyIsDown(RIGHT_ARROW)) {
  325.               direction = COUNTERCLOCKWISE;
  326.               speed = 1;
  327.               slowdown = 1;
  328.             }
  329.       break;
  330.   }
  331.     
  332.     for (i = 0; i < speed; i ++) {
  333.         if (direction == COUNTERCLOCKWISE) {
  334.           MovePaddleCounterClockwise(game, gameRect);
  335.         }
  336.         else if (direction == CLOCKWISE) {
  337.             MovePaddleClockwise(game, gameRect);
  338.         }
  339.     }
  340.  
  341.     /* BALL */
  342.     
  343.     {
  344.       static int rise[] = { -4,-3,-2,-1, 0, 1, 2, 3, 4 };
  345.       Rect ball,paddRect,dud,inset;
  346.       Point bp;
  347.       molecule *m = (**infoHand).molecule;
  348.       
  349.       game->ballx += game->balldx;
  350.       game->bally += game->balldy;
  351.       
  352.       /* detect collisions */ 
  353.       ball.left = game->ballx - BALLSIZEHALF;
  354.       ball.right = game->ballx + BALLSIZEHALF;
  355.       ball.top = game->bally - BALLSIZEHALF;
  356.       ball.bottom = game->bally + BALLSIZEHALF;
  357.       
  358.         paddRect.left = game->paddx - PADDSIZEHALF;
  359.         paddRect.right = game->paddx + PADDSIZEHALF;
  360.          paddRect.top = game->paddy - PADDSIZEHALF;
  361.         paddRect.bottom = game->paddy + PADDSIZEHALF;
  362.        
  363.     bp.h = game->ballx;
  364.     bp.v = game->bally;
  365.     inset = *gameRect;
  366.     InsetRect(&inset,PADDSIZEHALF-2,PADDSIZEHALF-2);
  367.  
  368.     /* test 1, out of bounds */
  369.        if (SectRect(&ball,&paddRect,&dud)) {
  370.          /* In Paddle */
  371.          int distance;
  372.          distance = sqrt(
  373.            ((game->paddx - game->ballx) * (game->paddx - game->ballx)) +
  374.            ((game->paddy - game->bally) * (game->paddy - game->bally)) );
  375.          distance %= 5;
  376.          if (distance == 0) {
  377.            distance = 1;
  378.          }
  379.          
  380.           if (game->paddx == gameRect->left) {
  381.               game->balldx = +distance;
  382.               game->balldy = (Random() % 5);
  383.           }
  384.           else if (game->paddx == gameRect->right) {
  385.               game->balldx = -distance;
  386.               game->balldy = (Random() % 5);
  387.           }
  388.           else if (game->paddy == gameRect->top) {
  389.           game->balldy = +distance;
  390.               game->balldx = (Random() % 5);
  391.       }
  392.           else if (game->paddy == gameRect->bottom) {
  393.           game->balldy = -distance;
  394.               game->balldx = (Random() % 5);
  395.           }
  396.           
  397.           game->ballx += game->balldx;
  398.           game->bally += game->balldy;
  399.       }
  400.     else if (!PtInRect(bp,&inset)) {
  401.       /* Out of bounds */
  402.             MoleculeSunRise();
  403.             GameStartup(game, gameRect, game->theWindow);
  404.     }
  405.       else {
  406.           int rowbytes;
  407.           unsigned char *pix;
  408.           molecule *m;
  409.           
  410.             rowbytes = (**infoHand).canvas.srow;
  411.             pix = (unsigned char *) (**infoHand).pixels;
  412.             m = (**infoHand).molecule;
  413.             
  414.             if (*(pix + (game->bally * rowbytes) + game->ballx) != CTABLEBKGND) {
  415.               /* not background color */
  416.  
  417.                 atom                *a;
  418.                 int                    err;
  419.                 char                *aexp;
  420.  
  421.                 err = pick_atom(m, bp.h, bp.v,&a);
  422.                 if (!err && a != NIL) { 
  423.                     aexp = atom_name(a);
  424.                     aexp = ConvertExpression(aexp,ATOMEXP);
  425.  
  426.                     kt_DeselectAllAtoms(m);
  427.                     kt_SelectOnscreenAtoms(m, aexp, SEL_SET | SEL_ONSCREEN);
  428.                   kt_HideSelection(m);
  429.  
  430.     #ifndef MACMOLECULE_LITE
  431.                     {
  432.                       char mess[255];
  433.                       int atms;
  434.                         select_atoms(m, NULL, SEL_ALL | SEL_ONSCREEN);
  435.                         atms = select_size(m, DO_ATOMS);
  436.                         select_atoms(m, NULL, SEL_CLEAR);
  437.                         
  438.                         if (atms == 0) {
  439.                           sprintf(mess,"You win! Now get back to work! (Click to continue)");
  440.                             game->state = OVER;
  441.                         }
  442.                         else {
  443.                             sprintf(mess,"Atoms remaining: %d",atms);
  444.                         }
  445.                         DrawTextMessage(game->theWindow, mess);
  446.                     }
  447.     #endif
  448.  
  449.                   do {
  450.                       game->balldx = (Random() % 5);
  451.                   game->balldy = (Random() % 5);
  452.               } while (game->balldx == 0 && game->balldy == 0);
  453.         }
  454.             }
  455.         }
  456.       
  457.       DrawGame(game, gameRect);
  458.       
  459.     }
  460.  
  461. }
  462.  
  463.  
  464. void GameMain(WindowPtr theWindow)
  465. {
  466.   DocInfoHand        infoHand;
  467.   static GameState game;
  468.     static int        inited = 0;
  469.     Rect                    gameRect;
  470.     
  471.     if (!IsMolWindow(theWindow))
  472.         return;
  473.     
  474.     infoHand = (DocInfoHand) osGetWRefCon(theWindow);
  475.     
  476.     if (!inited) {
  477.       GameInit(&game);
  478.       inited = 1;
  479.     }
  480.     
  481.     StartUsingPixMap(infoHand,left);
  482.  
  483.     GetGameRect(theWindow, &gameRect);
  484.     
  485.     switch (game.state) {
  486.         case STARTUP:
  487.             GameStartup(&game,&gameRect,theWindow);
  488.           break;
  489.         
  490.         case PLAYING:
  491.           GamePlaying(&game,&gameRect);
  492.           break;
  493.         
  494.         case PAUSED:
  495.           break;
  496.           
  497.         case OVER:
  498.           break;
  499.     }
  500.     
  501.     StopUsingPixMap(infoHand);
  502.     
  503. }
  504.  
  505.  
  506. /* called from SetLightSource, but with Option-Key held down */
  507. void MoleculeSunRise(void)
  508. {
  509.     WindowPtr        theWindow;
  510.     DocInfoHand    infoHand;
  511.     molecule        *m;
  512.     int                  orig_doly;
  513.     int         doly;
  514.     
  515.     theWindow = osFrontWindow();
  516.     if (!IsMolWindow(theWindow))
  517.         return;
  518.     
  519.     infoHand = (DocInfoHand) osGetWRefCon(theWindow);
  520.     m = (**infoHand).molecule;
  521.     
  522.     /*****/
  523.     
  524.     orig_doly = (**infoHand).doly;
  525.     for (doly = orig_doly - 6;
  526.          !(orig_doly - 5 < doly && doly < orig_doly + 5);
  527.          doly -= 5) {
  528.         if (osUserEventAvailable()) {
  529.           break;
  530.       }
  531.          
  532.          if (doly < -180) {
  533.            doly = 180;
  534.          }
  535.          
  536.       (**infoHand).doly = doly;
  537.  
  538.       SetMoleculeViewType(infoHand);
  539.       RenderMolecule(infoHand);
  540.  
  541.         DrawMoleculeProper(theWindow);
  542.         
  543.         {
  544.           long dud;
  545.             osDelay(1,&dud);
  546.         }
  547.     }
  548.  
  549.     (**infoHand).doly = orig_doly;
  550.  
  551.     SetMoleculeViewType(infoHand);
  552.     RenderMolecule(infoHand);
  553.  
  554.     DrawMoleculeProper(theWindow);
  555. }
  556.  
  557. /* End fun stuff */
  558.